#include "dat2.h"
#include<stdio.h>
#include<stdlib.h>


status init_list(sqlist *l){
	//sqlist* s=(sqlist*)malloc(sizeof(sqlist));
	//if(!s) exit(overflow);
	//s->next=NULL;
	//*l=*s;
	l->next=NULL;
	return ok;
}

void destroy_list(sqlist *l){
	sqlist *p,*q;
	p=l->next;
	while(p){
		q=p->next;
		free(p);
		p=q;
	}
	l=NULL;
}

void clear_list(sqlist *l){
	sqlist *p,*q;
	p=l->next;
	while(p){
		q=p->next;
		free(p);
		p=q;
	}
	l->next=NULL;
}
/*judge whether it is empty*/
status is_empty(sqlist *l){
	if(l->next){
		return false;
	}else{
		return true;
	}
}

int get_length(sqlist *l){
	int len=0;
	sqlist *p;
	p=l->next;
	while(p){
		len++;
		p=p->next;
	}
	return len;
}

status get_elem(sqlist *l,int i,redtype* e){
	if(i<1 || i>get_length(l)){
		return error;
	}
	sqlist *p;
	p=l;
	while(p && i>0){
		p=p->next;
		i--;
	}
	*e=p->data;
	return ok;
}

int cmp(redtype a,redtype b){
	return a.elem-b.elem;
}
int cmp_elem(elemtype a,elemtype b){
	return a-b;
}

void locate_elem(sqlist *l,elemtype e,func_cmp_elem op,sqlist **n){
	sqlist *p;
	p=l->next;
	while(p && op(p->data.elem,e)!=0){
		p=p->next;
	}
	if(p) *n=p;
}

status prior_elem(sqlist *l,elemtype e,sqlist **n){
	sqlist *p,*q;
	p=l,q=l->next;
	while(q){
		if(q->data.elem==e){
			*n=p;
			return ok;
		}
		p=q;
		q=q->next;
	}
	return error;
}

status next_elem(sqlist *l,elemtype e,sqlist **n){
	sqlist *p,*q;
	p=l->next;
	while(p){
		if(p->data.elem==e){
			*n=p->next;
			return ok;
		}
		p=p->next;
	}
	return error;
}

status list_insert(sqlist *l,int i,elemtype e){
	if(i<1 || i>get_length(l)+1){
		return error;
	}
	sqlist *node=(sqlist*)malloc(sizeof(sqlist));
	if(!node)exit(overflow);
	node->next=NULL;
	node->data.elem=e;
	sqlist *p,*q;
	p=l;
	while(p && i>1){
		p=p->next;
		i--;
	}
	q=p->next;
	p->next=node;
	node->next=q;
	return ok;
}
status list_insert_head(sqlist *l,elemtype e){
	sqlist *node=(sqlist*)malloc(sizeof(sqlist));
	if(!node)exit(overflow);
	node->next=NULL;
	node->data.elem=e;
	node->next=l->next;
	l->next=node;
	return ok;
}
status list_insert_tail(sqlist *l,elemtype e){
	sqlist *node=(sqlist*)malloc(sizeof(sqlist));
	if(!node)exit(overflow);
	node->next=NULL;
	node->data.elem=e;
	sqlist *p;
	p=l;
	while(p && p->next){
		p=p->next;
	}
	p->next=node;
	return ok;
}

status list_delete_elem(sqlist *l,elemtype e){
	sqlist *p,*q;
	p=l;
	while(p){
		q=p->next;
		if(cmp_elem(q->data.elem,e)==0)break;
		p=q;
	}
	if(q){
		p->next=q->next;
		free(q);
		return ok;
	}
	return error;

}
status list_delete(sqlist *l,int i){
	if(i<1 || i>get_length(l)){
		return error;
	}
	sqlist *p,*q;
	p=l;
	while(i>1){
		p=p->next;
		--i;
	}
	q=p->next;
	p->next=p->next->next;
	free(q);

}

void visited(redtype r){
	printf("%d ",r.elem);
}

void list_traverse(sqlist *l,func_visit op){
	sqlist *p;
	p=l->next;
	while(p){
		op(p->data);
		p=p->next;
	}
	printf("\n");
}

status print_list_elem(sqlist*l){
	sqlist *p;
	p=l->next;
	while(p){
		printf("%d ",p->data.elem);
		p=p->next;
	}
	printf("\n");
	return ok;
}

int main(){
	sqlist l;
    init_list(&l);
    list_insert(&l,1,1);
    list_insert(&l,2,2);
    list_insert(&l,3,3);
    list_insert(&l,4,4);
    list_insert(&l,5,5);
    list_insert(&l,6,6);
    list_insert(&l,7,7);
    list_insert(&l,8,8);
    list_insert(&l,9,9);
    list_insert(&l,10,10);
    list_insert(&l,11,11);
    list_insert(&l,12,12);
    list_insert(&l,13,13);
    list_insert(&l,14,14);
    list_insert(&l,10,100);
    print_list_elem(&l);
    printf("the length of the list:%d\n",get_length(&l));
    printf("the is_empty of the list:%d\n",is_empty(&l));
    redtype e;
    get_elem(&l,10,&e);
    printf("the get_elem,%d\n",e.elem);
	sqlist *result;
	locate_elem(&l,100,cmp_elem,&result);
	printf("the locate_elem:%d\n",result->data.elem);
    prior_elem(&l,100,&result);
    printf("the prior_elem:%d\n",result->data.elem);
    next_elem(&l,100,&result);
    printf("the of next_elem:%d\n",result->data.elem);
	list_insert_head(&l,101);
	list_insert_head(&l,102);
	list_insert_head(&l,103);
	list_insert_tail(&l,104);
	list_insert_tail(&l,105);
    list_traverse(&l,visited);
////redtype *e1;
////next_elem(l,3,&e1);
////printf("the elem 3 of next_elem:%d\n",e1->elem);
////list_insert(l,10,100);
////list_insert(l,1,0);
////print_list_elem(&l);
	list_delete_elem(&l,100);
    list_delete(&l,1);
    list_delete(&l,12);
    list_traverse(&l,visited);
    clear_list(&l);
   // print_list_elem(&l);
    destroy_list(&l);
}
 
